package com.ezandroid.library.image.ext.core.display;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;

import com.nostra13.universalimageloader.core.assist.LoadedFrom;
import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
import com.nostra13.universalimageloader.core.imageaware.ImageAware;

/**
 * 渐进显示图片
 * Created by huanqin on 16/5/26.
 */
public class FadeInBitmapDisplayer implements BitmapDisplayer {

    private final int durationMillis;

    private final boolean animateFromNetwork;
    private final boolean animateFromDisk;
    private final boolean animateFromMemory;
    private Context mContext;

    /**
     * @param durationMillis Duration of "fade-in" animation (in milliseconds)
     */
    public FadeInBitmapDisplayer(Context context, int durationMillis) {
        this(context, durationMillis, true, true, true);
    }

    /**
     * @param durationMillis     Duration of "fade-in" animation (in milliseconds)
     * @param animateFromNetwork Whether animation should be played if image is loaded from network
     * @param animateFromDisk    Whether animation should be played if image is loaded from disk cache
     * @param animateFromMemory  Whether animation should be played if image is loaded from memory cache
     */
    public FadeInBitmapDisplayer(Context context, int durationMillis, boolean animateFromNetwork, boolean animateFromDisk,
                                 boolean animateFromMemory) {
        this.durationMillis = durationMillis;
        this.animateFromNetwork = animateFromNetwork;
        this.animateFromDisk = animateFromDisk;
        this.animateFromMemory = animateFromMemory;
        mContext = context;
    }

    @Override
    public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
        Drawable old;
        if (imageAware.getWrappedView() instanceof ImageView) {
            old = ((ImageView) imageAware.getWrappedView()).getDrawable();
        } else {
            old = imageAware.getWrappedView().getBackground();
        }

        if ((animateFromNetwork && loadedFrom == LoadedFrom.NETWORK) ||
                (animateFromDisk && loadedFrom == LoadedFrom.DISC_CACHE) ||
                (animateFromMemory && loadedFrom == LoadedFrom.MEMORY_CACHE)) {
            if (old == null) {
                imageAware.setImageBitmap(bitmap);
                animate(imageAware.getWrappedView(), durationMillis);
            } else {
                Drawable[] drawables = new Drawable[]{old, new BitmapDrawable(mContext.getResources(), bitmap)};
                animate(imageAware, drawables, durationMillis);
            }
        } else {
            imageAware.setImageBitmap(bitmap);
        }
    }

    /**
     * Animates {@link ImageView} with "fade-in" effect
     *
     * @param imageView      {@link ImageView} which display image in
     * @param durationMillis The length of the animation in milliseconds
     */
    public static void animate(View imageView, int durationMillis) {
        if (imageView != null) {
            AlphaAnimation fadeImage = new AlphaAnimation(0, 1);
            fadeImage.setDuration(durationMillis);
            fadeImage.setInterpolator(new DecelerateInterpolator());
            imageView.startAnimation(fadeImage);
        }
    }

    public static void animate(ImageAware imageAware, Drawable[] drawables, int durationMillis) {
        TransitionDrawable drawable = new TransitionDrawable(drawables);
        for (int i = 0; i < drawables.length; i++) {
            drawable.setId(i, i);
        }
        drawable.startTransition(durationMillis);
        imageAware.setImageDrawable(drawable);
    }
}
